// 路由权限控制
import router, { constRoutes } from './router'
import { asyncRoutes } from './router'
import store from './store'

import errorRouter from '@/router/modules/404'

const WHITE_LIST = ['/login', '/404']

// 处理一级路由权限数据
function getFirstRoutePerms(permsArr) {
  const newArr = permsArr.map(item => {
    return item.split(':')[0]
  })
  return [...new Set(newArr)]
}

// 处理二级路由权限数据
function getSecondRoutePerms(permsArr) {
  const newArr = permsArr.map(item => {
    const itemArr = item.split(':')
    return `${itemArr[0]}:${itemArr[1]}`
  })
  return [...new Set(newArr)]
}

// 根据权限数据过滤动态路由
function filterRoutes(firstRoutePerms, secondRoutePerms, asyncRoutes) {
  return asyncRoutes.filter(route => {
    if (firstRoutePerms.length === 1 && firstRoutePerms[0] === '*') {
      return true
    }
    return firstRoutePerms.includes(route.permission)
  }).map(item => {
    if (secondRoutePerms.length === 1 && secondRoutePerms[0] === '*:*') {
      return item
    }
    return {
      ...item,
      children: item.children.filter(route => {
        return secondRoutePerms.includes(route.permission.split(':')[0] + ':' + route.permission.split(':')[1])
      })
    }
  })
}

// 路由前置守卫
router.beforeEach(async(to, from, next) => {
  const token = store.getters.token
  if (token) {
    // 如果有令牌
    if (to.path === '/login') {
      // 如果用户已经登录，并且访问的是登录页面，则跳转到首页
      next('/')
    } else if (!store.getters.profile.id) {
      // 如果没有登录用户的角色和权限等信息，立即获取
      await store.dispatch('user/getProfile')

      const perms = store.getters.profile.permissions
      // 获取一级路由权限
      const firstRoutePerms = getFirstRoutePerms(perms)
      // 获取二级路由权限
      const secondRoutePerms = getSecondRoutePerms(perms)
      // 过滤动态路由
      const filteredRoutes = filterRoutes(firstRoutePerms, secondRoutePerms, asyncRoutes)
      // 如果已经有了动态路由，则先清空动态路由信息，防止重复添加
      if (router.options.routes.length > constRoutes.length) {
        store.commit('user/clearMenuList')
      }
      // 添加动态路由
      filteredRoutes.forEach(route => {
        router.addRoute(route)
      })
      // 添加404页面
      router.addRoute(errorRouter)
      // 添加动态路由信息到vuex中的菜单栏列表中
      store.commit('user/setMenuList', filteredRoutes)
      // 循环跳转到目标路由直至动态路由加载完成
      next({ ...to, replace: true })
    } else {
      next()
    }
  } else {
    // 如果没有令牌
    if (WHITE_LIST.includes(to.path)) {
      // 如果是白名单中的路由，直接跳转
      next()
    } else {
      // 如果不是白名单中的路由，拦截到登录页
      next('/login')
    }
  }
})
